﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Poligono.Core
{
    /// <summary>
    /// Dispose Control Class, help to manager a dispose
    /// </summary>
    [Serializable]
    public abstract class DisposeControl : IDisposable
    {
        #region Privates Members
        private bool _IsDisposed = false;

        /// <summary>
        /// Object was disposed
        /// </summary>
        public bool IsDisposed
        {
            get { return _IsDisposed; }
            //private set { _IsDisposed = value; } is not fast
        }
        
        #endregion

        
        /// <summary>
        /// Basic Constructor
        /// </summary>
        public DisposeControl()
        {
            _IsDisposed = false;
        }

        #region IDisposable Members
        
        /// <summary>
        /// Dispode Method
        /// </summary>
        public void Dispose()
        {
            //The object will be deallocated by the Dispose method.
            Dispose(true);
            //Supress GC send object to Dispose
            GC.SuppressFinalize(this);
        }
        

        /// <summary>
        /// Internal Dispose method
        /// <remarks>call by internal class to help dipose</remarks>
        /// </summary>
        /// <param name="diposing">if dipose started</param>
        protected virtual void Dispose(bool diposing)
        {
            if (!IsDisposed)
            {
                if (diposing)
                {
                    _IsDisposed = true;
                }
            }
            //base.Dispose();
        }

        
        /// <summary>
        /// Disposed called by GC
        /// </summary>
        ~DisposeControl()
        {
            //Pass false as param because no need free managed resources when you call finalize
            Dispose(false);
        }

        #endregion

        /// <summary>
        /// MensagemErro throw when has a Exception<see cref="ObjectDisposedException"/> na
        /// chamada de <see cref="IsDisposed"/>
        /// </summary>
        protected abstract string MensagemErroObjectDisposedException
        {
            get;
        }

        /// <summary>
        /// Verify if Dispose be called
        /// </summary>
        public void CheckDispose()
        {
            if (_IsDisposed)
                throw new System.ObjectDisposedException(MensagemErroObjectDisposedException);
        }

        /*

        #region new Keywords

        /// <summary>
        /// override to operator ==, necessary because we use Dispose
        /// </summary>
        /// <param name="LeftDisposeControl">DisposeControl <see cref="DisposeControl"/></param>
        /// <param name="RightDisposeControl">DisposeControl <see cref="DisposeControl"/></param>
        /// <returns>return true if is same DisposeControl</returns>
        public static bool operator ==(DisposeControl LeftDisposeControl, DisposeControl RightDisposeControl)
        {
            bool leftNull, rightNull;
            leftNull = (LeftDisposeControl == null);
            rightNull = (RightDisposeControl == null);

            if (leftNull && rightNull)
                return true;
            else if (leftNull || rightNull)
                return false;
            else
                return LeftDisposeControl.Equals(RightDisposeControl);
        }

        /// <summary>
        /// override to operator ==, necessary because we use Dispose
        /// </summary>
        /// <param name="LeftDisposeControl">DisposeControl <see cref="DisposeControl"/></param>
        /// <param name="RightDisposeControl">DisposeControl <see cref="DisposeControl"/></param>
        /// <returns>return true if isn't same DisposeControl</returns>
        public static bool operator !=(DisposeControl LeftDisposeControl, DisposeControl RightDisposeControl)
        {
            return !(LeftDisposeControl == RightDisposeControl);
        }

        /// <summary>
        /// HashCode of <see cref="DisposeControl"/> 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Equal of <see cref="DisposeControl"/> 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }


        #endregion
        */
    }
}
